﻿#include <QDebug>
#include <QHostAddress>
#include <QTimer>
#include <QThreadPool>
#include "CWebSocketSrvThread.h"
#include "CPublicData.h"
#include "CLogOper.h"
#include "CHeader.h"
#include "CDevFollow.h"

CWebSocketSrvThread::CWebSocketSrvThread()
{
	m_pWebSocketServer = nullptr;
	m_bIsInit = false;
	QThreadPool::globalInstance()->setMaxThreadCount(16);
	CDevFollow::getInstance();
}

CWebSocketSrvThread::~CWebSocketSrvThread()
{
    clearClient();//清除客户端

    if(m_pWebSocketServer != nullptr)
    {
        m_pWebSocketServer->close();//调用close将使QWebSocketServer停止侦听传入的连接
		m_pWebSocketServer->deleteLater();
    }

}

void CWebSocketSrvThread::slotWorkProc()
{
	//首先做相关的初始化工作
	initSrv();
	while (false == m_bStopWorkThread)
	{
		if (!m_bIsInit)
		{
			initSrv();
		}

		QEventLoop loop;
		QTimer::singleShot(500, &loop, SLOT(quit()));
		loop.exec();//延时500毫秒
	}
}

//初始化服务
void CWebSocketSrvThread::initSrv()
{
	if (m_pWebSocketServer!=nullptr)
	{
		m_pWebSocketServer->close();
		delete m_pWebSocketServer;
		m_pWebSocketServer = nullptr;
	}
    m_pWebSocketServer = new QWebSocketServer(QStringLiteral("webSocketServer"),QWebSocketServer::NonSecureMode,this);
    connect(m_pWebSocketServer, &QWebSocketServer::newConnection, this, &CWebSocketSrvThread::getNewConnection);//每次客户端连接到服务器时都会发出newConnection信号

	int nPort = CPublicData::instance().m_nWebSocketPort;
	m_bIsInit = m_pWebSocketServer->listen(QHostAddress::Any, 12590);//监听端口 服务器监听传入的连接
	if (m_bIsInit)
	{
		SExecLog sLog;
		sLog.m_nAlarmLevel = enWorkInfo;
		sLog.m_sDescriptionl = A2T("初始化WebSocket服务成功");
		sLog.m_sDevName = A2T("机器人");
		sLog.m_sFuncName = A2T("主程序");
		CLogOper::instance().addMsg(sLog);
	}
    qDebug() << QStringLiteral("CWebSocketSrvThread初始化完成") << endl;
}

void CWebSocketSrvThread::onError(QAbstractSocket::SocketError error)
{
    QWebSocket * webSocket = qobject_cast<QWebSocket *>(sender());
}

void CWebSocketSrvThread::disConnect()
{
	QWebSocket *pWebSocket = qobject_cast<QWebSocket *>(sender()); // 获取发送信号的对象
	QMutexLocker ml(&m_mxClient);
	for(int i=0;i<m_vecClient.size();i++)
	{
		CWebSocketClient *pClient = m_vecClient[i];
		if (pClient->GetWebSocketClient() == pWebSocket)
		{
			m_vecClient.remove(m_vecClient.indexOf(pClient));
			if (pClient)
			{
				delete pClient;
				pClient = nullptr;
			}
			break;
		}
		else
		{
			continue;
		}
	}

	pWebSocket->deleteLater();
}

//当有新连接过来时处理
void CWebSocketSrvThread::getNewConnection()
{
    QString strTemp = "";
    if(m_pWebSocketServer->hasPendingConnections()) //有未处理的连接
    {
        //调用nextPendingConnection将挂起的连接接受为已连接的QWebSocket
        //函数返回指向QabstractSocket::ConnectedState中QWebSocket的指针
        //可以使用该指针与客户端通信
        QWebSocket * pWebSocket = m_pWebSocketServer->nextPendingConnection();
        if (pWebSocket == nullptr)
        {
            return;
        }
		//获取新连接客户端的ip
		QHostAddress clientAddress = pWebSocket->peerAddress();
		QString sClientIp = clientAddress.toString().remove(0,7);
        //开始new Client 传入存储连接的客户端 并且 处理相关所需返回数据
        CWebSocketClient *pClient = new CWebSocketClient(this, pWebSocket, sClientIp);

		QMutexLocker ml(&m_mxClient);
		m_vecClient.append(pClient);
        //关联客户端结束连接
		connect(pWebSocket, &QWebSocket::disconnected, this, &CWebSocketSrvThread::disConnect);
        //关联收到消息
        connect(pWebSocket,&QWebSocket::textMessageReceived,this,&CWebSocketSrvThread::ReceivedMsg);
        //关联错误信息
        connect(pWebSocket, SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError(QAbstractSocket::SocketError)));//这里参数是枚举 用qt5的方式这里编译不过
    }
}

//收到消息时的处理
void CWebSocketSrvThread::ReceivedMsg(const QString &message)
{
	QWebSocket *pWebSocket = qobject_cast<QWebSocket *>(sender()); // 获取发送信号的对象
	QString sMsg = message;
	for (int i = 0; i < m_vecClient.size(); i++)
	{
		CWebSocketClient *pClient = m_vecClient[i];
		if (pClient->GetWebSocketClient() == pWebSocket)
		{
			pClient->handleRequest(sMsg);
			break;
		}
		else
		{
			continue;
		}
	}
}

//清除客户端
void CWebSocketSrvThread::clearClient()
{
    QMutexLocker ml(&m_mxClient);
    while(m_vecClient.size())
    {
        delete m_vecClient[0];
        m_vecClient[0] = nullptr;
        m_vecClient.removeAt(0);
    }
}

//判断是否是有效的ip地址
bool CWebSocketSrvThread::isValidIPAddress(const QString &ipAddress)
{
    QHostAddress address(ipAddress);
    return address.protocol() == QAbstractSocket::IPv4Protocol ||
            address.protocol() == QAbstractSocket::IPv6Protocol;
}
